﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.WebControls.WebParts;
using System.ComponentModel;


namespace IntelligentDecisioning.SharePoint.WebParts.charts
{
    /// <summary>
    /// Chart webpart
    /// </summary>
    public class IDChartWebPart: IDWebPartBase
    {
        #region Data

        // The chart control
        private Chart _chart;

        // The visual representation of the chart
        private ChartArea _chartArea;

        // the data to display
        private Series _chartDataSeries;

        #endregion

        #region WebPart Properties

        public bool EnableTracing { get; set; }

        #region Demo Mode

        [Personalizable(PersonalizationScope.Shared),
         WebBrowsable(true),
         WebDisplayName("Demo Mode"),
         WebDescription("Various demonstration charts"),
         Category("IDChart")]
        public DemoMode DemoMode { get; set; }

        #endregion

        #endregion

        #region Webpart Lifecycle Methods

        protected override void CreateChildControls()
        {
            try
            {
                ConfigureChart();
                AddDataToChart();
                base.Controls.Add(_chart);
            }
            catch (Exception e)
            {
                AddErrorControl(e);
            }
        }

        #endregion

        #region Configure Chart

        /// <summary>
        /// Configures the chart - override this method to add your own configuration
        /// </summary>
        protected virtual void ConfigureChart()
        {
            ChartConfiguration config = GetDemoChartConfiguration();
            ConfigureChart(config);
        }

        /// <summary>
        /// Creates configuration for a demonstration chart
        /// </summary>
        /// <returns></returns>
        private ChartConfiguration GetDemoChartConfiguration()
        {
            ChartConfiguration config = new ChartConfiguration();
            config.Title = "Id-SharePoint Demonstration Chart WebPart";
            config.Width = 600;
            config.Height = 600;

            switch (DemoMode)
            {
                case DemoMode.Pie:
                    config.Draw3D = true;
                    config.Pallete = ChartColorPalette.BrightPastel;
                    break;
                case DemoMode.Line:
                    config.Draw3D = true;
                    config.AxisMarginVisible = true;
                    break;
                case DemoMode.Bar:
                    config.Draw3D = true;
                    config.AxisXTitle = "Test X";
                    config.AxisYTitle = "Test Y";
                    break;
                default:
                    break;
            }

            return config;
        }

        #endregion

        #region Add Data to Chart

        protected virtual void AddDataToChart()
        {
            ChartData data = GetChartData();
            AddDataToChart(data);
        }


        private ChartData GetChartData()
        {
            ChartData data = new ChartData();
            Series data2009Series = new Series("2009");

            String[] regions = new string[] { "North", "South", "East", "West", "Other" };
            int[] dataValues = new int[] { 300, 50, 468, 93, 211 };
            data2009Series.Points.DataBindXY(regions, dataValues);

            switch (DemoMode)
            {
                case DemoMode.Pie:
                    data2009Series.ChartType = SeriesChartType.Pie;
                    data2009Series.Points[3]["Exploded"] = "true";
                    data2009Series["PieLabelStyle"] = "Outside";
                    data2009Series["PieDrawingStyle"] = "SoftEdge";
                    data2009Series.BackGradientStyle = GradientStyle.DiagonalLeft;
                    break;
                case DemoMode.Line:
                    data2009Series.ChartType = SeriesChartType.Line;
                    // Set point labels
                    data2009Series.IsValueShownAsLabel = true;
                    // Show data point marker lines
                    data2009Series["ShowMarkerLines"] = "True";
                    break;
                case DemoMode.Bar:
                    data2009Series.ChartType = SeriesChartType.Bar;
                    // Set series point width
                    data2009Series["PointWidth"] = "0.6";
                    // Show data points labels
                    data2009Series.IsValueShownAsLabel = true;
                    // Set data points label style
                    data2009Series["BarLabelStyle"] = "Center";
                    break;
                default:
                    break;
            }

            data.Series = data2009Series;
            return data;
        }

        #endregion

        #region Add Error Control

        /// <summary>
        /// Attempts to display some useful diagnostic information
        /// when a error occurs drawing the chart. Override this method to 
        /// show a generic message of nothing.
        /// </summary>
        /// <param name="e">The exception</param>
        protected virtual void AddErrorControl(Exception e)
        {
            
            String errorMessage = "Unexpected exception while generating the IDChartPart. Message: " + e.Message;
            while(e.InnerException != null)
            {
                e = e.InnerException;
                errorMessage += " Inner exception details: " + e.Message;
            }

            Literal errorLiteral = new Literal();
            errorLiteral.Text = errorMessage;
            base.Controls.Add(errorLiteral);
        }

        #endregion

        #region Helper Methods

        #region Configure Chart

        /// <summary>
        /// A convenience method that allows a chart to be configured in code
        /// </summary>
        /// <param name="config"></param>
        protected void ConfigureChart(ChartConfiguration config)
        {
            _chart = new Chart();
            _chart.Titles.Add(config.Title);
            _chart.Height = config.Height;
            _chart.Width = config.Width;
            _chart.Palette = config.Pallete;

            _chartArea = new ChartArea();
            _chartArea.Area3DStyle.Enable3D = config.Draw3D;
            _chartArea.AxisX.Title = config.AxisXTitle;
            _chartArea.AxisY.Title = config.AxisYTitle;
            _chartArea.AxisX.IsMarginVisible = config.AxisMarginVisible;
            _chart.ChartAreas.Add(_chartArea);
        }

        #endregion

        #region Add Data to Chart

        /// <summary>
        /// A convenience method that allows data to be added to a chart in code
        /// </summary>
        protected void AddDataToChart(ChartData data)
        {
            _chartDataSeries = data.Series;
            _chart.Series.Add(_chartDataSeries);
        }

        #endregion

        #endregion
    }

    public enum DemoMode
    {
        Pie,
        Line,
        Bar
    }
}
